package compiladorglc.glc;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import compiladorglc.hash.Registro;

public class GLC {

	private static FileInputStream fis;
	
	public static void buildSource(String sourceCode) {
		
		try {
			
			fis = new FileInputStream("exemplo1.gl");
			
			while (fis.available() > 0) {
				
				proximo_token();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static Registro proximo_token() throws IOException {
		
		Integer estado = 0;

		while (true) {
			
			Character c = (char) fis.read();

			switch (estado) {
			
				/**
				 * Estado 0, começo da procura por novo token
				 */
				case 0:
					
					if (letra(c)) {
						estado = 1;
					} else if (digito(c)) {
						estado = 3;
					} else if (c=='.') {
						estado = 8;
					} else if (c=='>') {
						estado = 12;
					} else if (c=='<') {
						estado = 13;
					} else if (c=='=') {
						estado = 14;
					} else if (c=='+' || c=='-' || c=='*' || c=='/' || c=='('  || c==')' || c==',') {
						// retornar token
					}
					
					break;

			/**
			 * Palavras-Chave e Identificadores
			 */
			case 1:
				if (letra(c) || digito(c)) {
					estado = 1;
				} else {
					// Retornar ou intalar novo token
				}
				break;

			/**
			 * Estado final
			 */
			case 2:
				break;

			/**
			 * Estados 3-11 : Números inteiros e reais
			 */
			case 3:
				if (digito(c)) {
					estado = 4;
				} else if (c=='.') {
					estado = 8;
				} else {
					// retornar token de constante númerica
				}
				break;
			
			case 4:
				if (digito(c)) {
					estado = 5;
				} else if (c=='.') {
					estado = 8;
				} else {
					// retornar token de constante númerica
				}
				break;
			
			case 5:
				if (digito(c)) {
					estado = 6;
				} else if (c=='.') {
					estado = 8;
				} else {
					// retornar token de constante númerica
				}
				break;
			
			case 6:
				if (digito(c)) {
					estado = 7;
				} else if (c=='.') {
					estado = 8;
				} else {
					// retornar token de constante númerica
				}
				break;
			
			case 7:
				if (digito(c)) {
					estado = 7;
				} else {
					estado = 2;
					// retornar token de constante númerica
					// retroceder o caracter
					// fis.skip(-1); // Retroceder um byte
				}
				break;
			
			case 8:
				if (digito(c)) {
					estado = 9;
				} else if (!digito(c) && c!='.') {
					estado = 2;
					// retornar token de constante númerica real
				}
				break;
			
			case 9:
				if (digito(c)) {
					estado = 10;
				} else if (!digito(c) && c!='.') {
					estado = 2;
					// retornar token de constante númerica real
				}
				break;
			
			case 10:
				if (digito(c)) {
					estado = 11;
				} else if (!digito(c) && c!='.') {
					estado = 2;
					// retornar token de constante númerica real
				}
				break;
			
			case 11:
				if (digito(c)) {
					estado = 2;
					// retornar token
				} else {
					estado = 2;
					// retornar e retroceder VERIFICAR
				}
				break;
			
			/**
			 * Estados 12-14: Relacionamentos
			 */
			case 12:
				if (c=='=') {
					estado = 2;
					// retornar simbolo >=
				} else {
					estado = 2;
					// retornar simbolo >
				}
				break;
			
			case 13:
				if (c=='=') {
					estado = 2;
					// retornar <=
				} else if (c=='>') {
					// retornar <>
				} else {
					// retornar <
				}
				break;
				
			case 14:
				if (c=='=') {
					// retornar ==
				} else {
					// retornar =
				}
				break;
			
			/**
			 * 
			 */
			default:
				break;
			}
		}
	}

	private static boolean digito(Character c) {
		
		Integer asc = Character.getNumericValue(c);
		
		if (asc>=48 && asc<=57) {
			return true;
		} else {
			return false;
		}
	}

	private static boolean letra(Character c) {
		
		Integer asc = Character.getNumericValue(c);
		
		if (asc>=65 && asc<=122) {
			return true;
		} else {
			return false;
		}
	}
}
